#include "CVector2.h"
#include <math.h>
#include <float.h>


//####################################################################################################
//####################################################################################################
//		Constructors
//####################################################################################################
//####################################################################################################
//--------------------------------------------------------------------
//	Default Constructor
//--------------------------------------------------------------------
CVector2::CVector2() : x(0), y(0)
{}
//--------------------------------------------------------------------
//	Initated Constructor
//--------------------------------------------------------------------
CVector2::CVector2(float _X, float _Y) : x(_X), y(_Y)
{}
//--------------------------------------------------------------------
//	Initated Constructor
//--------------------------------------------------------------------
CVector2::CVector2(long  _X, long  _Y) : x(float(_X)), y(float(_Y))
{}
//--------------------------------------------------------------------
//	Initated Constructor
//--------------------------------------------------------------------
CVector2::CVector2(unsigned short  _X, unsigned short  _Y) : x(unsigned short(_X)), y(unsigned short(_Y))
{}
//--------------------------------------------------------------------
//	Copy Constructor
//--------------------------------------------------------------------
CVector2::CVector2(const CVector2& _vector)
{
	if(this != &_vector)
	{
		x = _vector.x;
		y = _vector.y;
	}
}

//####################################################################################################
//####################################################################################################
//		Operators
//####################################################################################################
//####################################################################################################
//--------------------------------------------------------------------
//	Addition Operator
//--------------------------------------------------------------------
CVector2 CVector2::operator+(CVector2 _vector)
{
	return CVector2((x+_vector.x),(y+_vector.y));
}
//--------------------------------------------------------------------
//	Substraction Operator
//--------------------------------------------------------------------
CVector2 CVector2::operator-(CVector2 _vector)
{
	return CVector2((x-_vector.x),(y-_vector.y));
}

//--------------------------------------------------------------------
//	Scalar Multiplication
//--------------------------------------------------------------------
CVector2 CVector2::operator*(float _num)
{
	return CVector2((x*_num),(y*_num));
}
//--------------------------------------------------------------------
//	Scalar Division
//--------------------------------------------------------------------
CVector2 CVector2::operator/(float _num)
{
	return CVector2((x/_num),(y/_num));
}

//--------------------------------------------------------------------
//	Returns the Maginitude of two vectors divided
//--------------------------------------------------------------------
float CVector2::operator/(CVector2 _vector)
{
	return ((Magnitude()) / (_vector.Magnitude()));
}
//--------------------------------------------------------------------
//	Check Magnitude
//	Due to the nature of floats it checks within a 5% tolerance
//--------------------------------------------------------------------
bool CVector2::operator==(float _mag) const
{
	float _result = Magnitude() / _mag;	
	return ((_result < 1.05f) || (_result > 0.95f));
}
//--------------------------------------------------------------------
//	Equal Comparison for Vectors
//	Due to the nature of floats it checks within a 5% tolerance
//--------------------------------------------------------------------
bool CVector2::operator==(CVector2 _vector) const
{
	float _result = ((x/_vector.x) + (y/_vector.y)) / 2.0f;
	return ((_result < 1.05f) || (_result > 0.95f));
}
//--------------------------------------------------------------------
//	Checks for inquality
//	Uses equality operator
//--------------------------------------------------------------------
bool CVector2::operator!=(CVector2 _vector) const
{
	return !((*this) == _vector);
}

//--------------------------------------------------------------------
//	Addition Operator
//--------------------------------------------------------------------
void CVector2::operator+=(CVector2 _vector)
{
	x += _vector.x;
	y += _vector.y;
}
//--------------------------------------------------------------------
//	Substraction Operator
//--------------------------------------------------------------------
void CVector2::operator-=(CVector2 _vector)
{
	x -= _vector.x;
	y -= _vector.y;
}

//--------------------------------------------------------------------
//	Scalar Multiplication
//--------------------------------------------------------------------
void CVector2::operator*=(float _num)
{
	x *= _num;
	y *= _num;
}
//--------------------------------------------------------------------
//	Scalar Division
//--------------------------------------------------------------------
void CVector2::operator/=(float _num)
{
	x /= _num;
	y /= _num;
}

//--------------------------------------------------------------------
//	Returns the Maginitude of two vectors divided
//--------------------------------------------------------------------
void CVector2::operator/=(CVector2 _vector)
{
	float _mag = _vector.Magnitude();
	x /= _mag;
	y /= _mag;
}

//####################################################################################################
//####################################################################################################
//		Functions
//####################################################################################################
//####################################################################################################
//--------------------------------------------------------------------
//	Normalizes the vector
//--------------------------------------------------------------------
void CVector2::Normalize()
{
	// Get the magnitude
	float _Magnitude = Magnitude();

	// Recalculate Lengths
	x /= _Magnitude;
	y /= _Magnitude;
}
//--------------------------------------------------------------------
//	Inverts all the values of the Vector
//--------------------------------------------------------------------
void CVector2::Invert()
{
	x = -x;
	y = -y;
}

//####################################################################################################
//####################################################################################################
//		Accessors
//####################################################################################################
//####################################################################################################
//--------------------------------------------------------------------
//	Returns Normalized form of the Vector
//--------------------------------------------------------------------
CVector2 CVector2::getNormalized() const
{
	// Get the magnitude
	float _Magnitude = Magnitude();
	CVector2 _normalized(x,y);

	// Recalculate Lengths
	_normalized.x /= _Magnitude;
	_normalized.y /= _Magnitude;

	return _normalized;
}
//--------------------------------------------------------------------
//	Returns the maginitude of the vector
//--------------------------------------------------------------------
float CVector2::Magnitude() const
{
	return (sqrt(pow(x,2) + pow(y,2)));
}
//--------------------------------------------------------------------
//	Gets the Dot product of the Vectors
//--------------------------------------------------------------------
float CVector2::Dot(CVector2 _vector) const
{
	return ((x * _vector.x) + (y * _vector.y));
}
//--------------------------------------------------------------------
//	Gets the angle between
//--------------------------------------------------------------------
float CVector2::Angle(CVector2 _vector) const
{
	float _angle = acos((float)(Dot(_vector) / (Magnitude() * _vector.Magnitude())));

	if(_isnan(_angle))
		return 0;

	// Return the angle in radians
	return(_angle);
}
